package wechat

import (
	"context"
	"errors"
	"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram"
	"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/auth/response"
	response2 "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/phoneNumber/response"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"golang-sgg-daijia/pkg/log"
)

type WeChatMiniClient interface {
	GetSession(ctx context.Context, code string) (*response.ResponseCode2Session, error)
	GetPhoneNoInfo(ctx context.Context, code string) (*response2.PhoneInfo, error)
}

type weChatMiniClient struct {
	wxMini *miniProgram.MiniProgram
	logger *log.Logger
}

func NewWeChatMiniCli(
	wxMini *miniProgram.MiniProgram,
	logger *log.Logger,
) WeChatMiniClient {
	return &weChatMiniClient{
		wxMini: wxMini,
		logger: logger,
	}
}

func NewWeChatMini(conf *viper.Viper) *miniProgram.MiniProgram {
	// 1. 初始化小程序应用实例
	app, err := miniProgram.NewMiniProgram(&miniProgram.UserConfig{
		AppID:     conf.GetString("security.wx.app_id"),     // 小程序、公众号或者企业微信的appid
		Secret:    conf.GetString("security.wx.app_secret"), // 商户号 appID
		HttpDebug: true,
		Debug:     false,
	})
	if err != nil {
		panic(err)
	}
	return app
}

func (w *weChatMiniClient) GetSession(ctx context.Context, code string) (*response.ResponseCode2Session, error) {
	session, err := w.wxMini.Auth.Session(ctx, code)
	if err != nil {
		w.logger.WithContext(ctx).Error("customerInfo|Login|Session", zap.Any("data", map[string]interface{}{
			"code": code,
		}), zap.Error(err))
		return nil, err
	}
	return session, nil
}

func (w *weChatMiniClient) GetPhoneNoInfo(ctx context.Context, code string) (*response2.PhoneInfo, error) {
	phoneRsp, err := w.wxMini.PhoneNumber.GetUserPhoneNumber(ctx, code)
	if err != nil || phoneRsp == nil || phoneRsp.ErrCode != 0 || phoneRsp.PhoneInfo == nil {
		w.logger.WithContext(ctx).Error("customerInfo|GetPhoneNoInfo|GetUserPhoneNumber", zap.Any("data", map[string]interface{}{
			"code":    code,
			"err msg": phoneRsp,
		}), zap.Error(err))
		return nil, errors.New("WXMiniProgram GetPhoneNoInfo error")
	}
	return phoneRsp.PhoneInfo, nil
}
